#include <string.h>
#include <stdlib.h>
#include <iostream>

using std::cout;
using std::endl;

//需求：只能创建堆对象，不能创建栈对象
//解决方案：将析构函数设置为私有的

class Student
{
public:
    Student(const char *name, int id)
    : _name(new char[strlen(name) + 1]())
    , _id(id)
    {
        cout << "Student(const char *, int)" <<endl;
        strcpy(_name, name);
    }
    
    //申请原始的未初始化的空间
    static void *operator new(size_t sz)
    {
        cout << "void *operator new(size_t )" << endl;
        //函数体该怎么实现呢
        void *pret = malloc(sz);

        return pret;
    }

    static void operator delete(void *ptr)
    {
        cout << "void operator delete(void *)" << endl;
        free(ptr);
    }

    void print() const
    {
        if(_name)
        {
            cout << "name: " << _name << endl; 
        }
        cout << "id: " << _id << endl;
    }

    //Student * const this
    void destroy()
    {
        //this指针，指向对象本身
        /* this->~Student();//显示调用析构函数 */
        delete this;//析构函数  执行operator delete
    }
private:
    //dt)  = del to )
    ~Student()
    {
        cout << "~Student()" << endl;
        /* delete this;//导致死循环 */
        if(_name)
        {
            delete [] _name;
            _name = nullptr;
        }
    }

private:
    char *_name;
    int _id;
};

void test()
{
    /* Student stu("xiaohong", 4201);//栈对象,error */
    /* stu.print(); */

    Student *pstu = new Student("lili", 4321);//堆对象，ok
    pstu->print();

    //类外面不行,放到类中
    /* delete pstu;//析构函数  operator delete */
    /* pstu = nullptr; */
    pstu->destroy();
    pstu = nullptr;
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

